/******************************************************************************
* Copyright (C) 2020 ShenZhen Powerdata Information Technology Co.,Ltd
* All Rights Reserved.
* 本软件为***研制。未经本公司正式书面同意，其他任何个人、团体不得使用、
* 复制、修改或发布本软件.
*****************************************************************************/

package com.xgf.common.xgfcommon.data.structure;

import java.util.ArrayList;
import java.util.Arrays;

/**
* @Title:数组公共类
* @ClassName:  ArraysUtils   
* @Description:TODO  
* @author: xgf
* @date:   2020年3月2日 下午1:46:28   
* @since   JDK1.8
* @history 2020年3月2日 TODO 新建
*/
public class ArraysUtils<T> {

	//新增
	//修改 
	//删除
	// -8  存了数组_length字段
	private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
	private int size;
	private T[] arrays = null;
	
	
	
	public ArraysUtils(int size) {
		this.size = 0;
		this.arrays = (T[]) new Object[size];
	}



	/**
	 * get 方法
	* @Title: get
	* @Description: TODO
	* @param @param index 获取数据的索引
	* @param @return 
	* @return T
	* @throws
	 */
	public T get(int index) {
		if(index < 0 || index > (arrays.length -1) ) {
			throw new ArrayIndexOutOfBoundsException("index过小 或者 数组越界");
		}
		return arrays[index];
	}
	
	/**
	 * 修改数组元素
	* @Title: update
	* @Description: TODO
	* @param @param index 要修改的元素的索引
	* @param @param content 要修改的内容
	* @param @return 
	* @return Boolean true 代表修改成功 false 代表修改失败
	* @throws
	 */
	public Boolean update(int index, T content) {
		if(index < 0 || index > (arrays.length -1) ) {
			throw new ArrayIndexOutOfBoundsException("index过小 或者 数组越界");
		}
		arrays[index] = content;
		return true;
	}



	/**
	 * 1.0 没有自动扩充，2.0是如果过了数组长度 自动扩充到 1.5倍
	 * 然后如果是中间的一位 我就需要往后面移动一位
	 * 
	 * 问题1：插入的index 大于现在有的总长度
	 * 问题2：插入的index 在中间 后面的数据都需要往后一位
	* @Title: add 往数组中添加元素
	* @Description: TODO
	* @param @param index
	* @param @param content 
	* @return void
	* @throws
	 */
	public void insert(int index, T content) {
		if(index < 0 || index > (arrays.length -1) ) {
			throw new ArrayIndexOutOfBoundsException("index过小 或者 数组越界");
		}
		//真实大小 大于等于 数组最大长度
		if(size >= arrays.length) {
			resize();
		}
		//如果不是最后一位 我都需要串位
		for (int i = size -1 ; i >= index ; i--) {
			arrays[i + 1 ] = arrays[i ];
			
		}

		
//		if(index >= defaultSize) {
//			grow(index + 1 );
//		}
		arrays[index] = content;
		size++;
	}
	

	/**
	 * 删除指定的索引元素
	* @Title: delete
	* @Description: TODO
	* @param @param index 要修改的索引
	* @param @return 
	* @return T
	* @throws
	 */
	public T delete(int index) {
		if(index < 0 || index >= size) {
			throw new ArrayIndexOutOfBoundsException("index过小 或者 数组越界");
		}
		if(index == 0) {
			
		}
		T result = arrays[index];
		for (int i = index; i < size - 1; i++) {
			arrays[i] = arrays[i + 1];
		}
		arrays[size - 1] = null;
		size--;
		return result;
	}




	private void resize() {
		T[] arraysReal = (T[]) new Object[size * 2];
		System.arraycopy(arrays, 0, arraysReal, 0, size);
		arrays = arraysReal;
	}








	public T[] getArrays() {
		return arrays;
	}






	public void setArrays(T[] arrays) {
		this.arrays = arrays;
	}






	public static void main(String[] args) {
		ArraysUtils<String> arraysUtils = new ArraysUtils<String>(5);
		
		for (int i = 0; i < 5; i++) {
			arraysUtils.insert(i, i + "");
			
		}
		arraysUtils.insert(2, "qwe");
		arraysUtils.sysoResult();
		System.out.println("---------------------");
		arraysUtils.delete(0);
		arraysUtils.sysoResult();
		
	}
	
	public void grow(Integer minCapacity) {
        int oldCapacity = arrays.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        arrays = Arrays.copyOf(arrays, newCapacity);
	}
	
    private static int hugeCapacity(int minCapacity) {
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError();
        return (minCapacity > MAX_ARRAY_SIZE) ?
            Integer.MAX_VALUE :
            MAX_ARRAY_SIZE;
    }
	
	public void sysoResult() {
		for (T t : arrays) {
			System.out.println(t);
		}
	}
}
